<template>
	<div class="editor">
		<TinymceEditor v-if="!switching" :id="tinymceId" v-model="value" :init="completeSetting" :disabled="disabled" />
	</div>
</template>
<script lang="ts" setup name="TinyMCE">
import tinymce from 'tinymce/tinymce'
import TinymceEditor from '@tinymce/tinymce-vue'
import 'tinymce/themes/silver/theme'
import 'tinymce/icons/default/icons'
import 'tinymce/models/dom'
import 'tinymce/plugins/autolink'
import 'tinymce/plugins/autoresize'
import 'tinymce/plugins/fullscreen'
import 'tinymce/plugins/image'
import 'tinymce/plugins/insertdatetime'
import 'tinymce/plugins/link'
import 'tinymce/plugins/lists'
import 'tinymce/plugins/media'
import 'tinymce/plugins/preview'
import 'tinymce/plugins/table'
import 'tinymce/plugins/wordcount'
import 'tinymce/plugins/code'
import 'tinymce/plugins/searchreplace'

// import useSettingsStore from '@/store/modules/settings'
import { computed, onMounted, ref, watch, nextTick } from 'vue'
import { GlobalStore } from '@/stores'
import { randomNum } from '@/utils/util'
const props = withDefaults(
	defineProps<{
		modelValue?: string
		setting?: { [key: string]: any }
		disabled?: boolean
	}>(),
	{
		setting: () => ({}),
		disabled: false
	}
)

// vmodel
const emits = defineEmits(['update:modelValue'])
const value = computed({
	get() {
		return props.modelValue
	},
	set(newVal) {
		emits('update:modelValue', newVal)
	}
})

const tinymceId = ref<string>('tinymce_' + randomNum(0, 10000000))

const globalStore = GlobalStore()
const isDark = computed(() => globalStore.themeConfig.isDark)
const defaultSetting = computed(() => {
	return {
		language_url: 'tinymce/langs/zh-Hans.js',
		language: 'zh-Hans',
		skin_url: isDark.value ? 'tinymce/skins/ui/oxide-dark' : 'tinymce/skins/ui/oxide',
		content_css: isDark.value ? 'tinymce/skins/content/dark/content.min.css' : 'tinymce/skins/content/default/content.min.css',
		min_height: 250,
		max_height: 600,
		selector: 'textarea',
		plugins: 'autolink autoresize fullscreen image insertdatetime link lists media preview table wordcount code searchreplace',
		toolbar:
			'undo redo | blocks | bold italic underline strikethrough | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | forecolor backcolor removeformat | link image media table insertdatetime searchreplace | preview code fullscreen',
		branding: false,
		menubar: false,
		resize: true,
		toolbar_mode: 'sliding',
		insertdatetime_formats: ['%Y年%m月%d日', '%H点%M分%S秒', '%Y-%m-%d', '%H:%M:%S'],
		// https://www.tiny.cloud/docs/tinymce/6/file-image-upload/#images_upload_handler
		images_upload_handler: (blobInfo: any) =>
			new Promise(resolve => {
				const img = `data:image/jpeg;base64,${blobInfo.base64()}`
				resolve(img)
			})
	}
})
const completeSetting = computed(() => {
	return Object.assign({}, defaultSetting.value, props.setting)
})

onMounted(() => {
	tinymce.init({})
})

// 用 v-if 和 nextTick 指令，强制组件重新加载。
const switching = ref(false)
// 监听配置，如果修改实现实例切换
watch(completeSetting, () => {
	const instance = tinymce.get(tinymceId.value)
	instance?.destroy()
	switching.value = true
	nextTick(() => {
		switching.value = false
	})
})
</script>

<style lang="scss" scoped>
:deep(.tox-tinymce) {
	border-radius: 4px;
}
</style>
